﻿using FinalPointSet.Model.Constant;
using FinalPointSet.Model.Constant.Message;
using FinalPointSet.Model.Constants;
using FinalPointSet.Model.Manager;
using FinalPointSet.Model.Util;
using HandyControl.Controls;
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Animation;
using Window = System.Windows.Window;

namespace FinalPointSet.View
{
    /// <summary>
    /// SearchView.xaml 的交互逻辑
    /// </summary>
    public partial class SearchView : Window
    {
        /// <summary>
        /// 窗体的状态
        /// </summary>
        private State WinState = State.Searching;
        /// <summary>
        /// 监听ID
        /// </summary>
        private readonly int growMsgListenID = -1;
        public SearchView()
        {
            InitializeComponent();
            tb_search.Focus();

            //添加窗体显示监听
            WindowUtil.Instance.OnWindowShow += OnWindowShow;

            //弹出信息处理
            int growMsgListenID = MessageManager.Listening(MsgType.GrowMsg, (msgArg) =>
            {
                if (msgArg is not GrowMsgArg growMsgArg)
                    return;
                if (!WindowType.SearchView.Equals(growMsgArg.WindowType))
                    return;
                Debug.Print("SearchView.Grow()");
                switch (growMsgArg.Key)
                {
                    case GrowlMsgType.Info:
                        Growl.Info(growMsgArg.Value);
                        break;
                    case GrowlMsgType.Success:
                        Growl.Success(growMsgArg.Value);
                        break;
                    case GrowlMsgType.Warning:
                        Growl.Warning(growMsgArg.Value);
                        break;
                    case GrowlMsgType.Error:
                        Growl.Error(growMsgArg.Value);
                        break;
                    case GrowlMsgType.Fatal:
                        Growl.Fatal(growMsgArg.Value);
                        break;
                    case GrowlMsgType.Clear:
                        Growl.Clear(growMsgArg.Value);
                        break;
                    default:
                        Growl.Info(growMsgArg.Value);
                        break;
                }
            });
        }

        /// <summary>
        /// 窗体显示
        /// </summary>
        /// <param name="windowName">窗体名称</param>
        private void OnWindowShow(string windowName)
        {
            if (Config.SearchView.Equals(windowName))
                tb_search.Focus();
        }

        /// <summary>
        /// 搜索框键盘输入事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SearchTextBoxKeyDown(object sender, KeyEventArgs e)
        {
            Debug.Print("SearchTextBoxKeyDown=" + e.Key.ToString());
            if (e.Key == Key.Enter)
            {
                ChangeWindowState(State.Detail);
            }
            else if (e.Key == Key.Escape && WinState == State.Searching)
            {
                WindowUtil.Instance.Hide(GetType());
            }
            else if (e.Key == Key.Escape)
            {
                ChangeWindowState(State.Searching);
            }
        }

        /// <summary>
        /// 更改窗体状态
        /// </summary>
        /// <param name="state"></param>
        private void ChangeWindowState(State state)
        {
            if (state == State.Detail && WinState != State.Detail)
            {
                Debug.Print($"ChangeWindowState={State.Detail}");
                DoubleAnimation doubleAnimation = new()
                {
                    Duration = new Duration(TimeSpan.FromSeconds(Config.SearchWindow_ShowKeywordDetail_AnimationDuartion)),
                    From = Config.SearchWindow_KeywordSearching_Height,
                    To = Config.SearchWindow_KeywordDetail_Height
                };
                BeginAnimation(HeightProperty, doubleAnimation);
            }
            else if (state == State.Searching && WinState != State.Searching)
            {
                Debug.Print($"ChangeWindowState={State.Searching}");
                DoubleAnimation doubleAnimation = new()
                {
                    Duration = new Duration(TimeSpan.FromSeconds(Config.SearchWindow_HideKeywordDetail_AnimationDuartion)),
                    From = Config.SearchWindow_KeywordDetail_Height,
                    To = Config.SearchWindow_KeywordSearching_Height
                };
                BeginAnimation(HeightProperty, doubleAnimation);
            }
            WinState = state;
        }


        /// <summary>
        /// 搜索窗体状态
        /// </summary>
        private enum State
        {
            /// <summary>
            /// 关键词输入中
            /// </summary>
            Searching = 0,
            /// <summary>
            /// 关键词详情
            /// </summary>
            Detail = 1
        }

        /// <summary>
        /// 检查是否退出键按下
        /// </summary>
        /// <param name="e"></param>
        private bool CheckIsEscKeyDown(KeyEventArgs e)
        {
            bool isEscKeyDown = false;
            if (e.Key == Key.Escape && WinState == State.Searching)
            {
                WindowUtil.Instance.Hide(GetType());
                isEscKeyDown = true;
            }
            else if (e.Key == Key.Escape)
            {
                ChangeWindowState(State.Searching);
                isEscKeyDown = true;
            }
            return isEscKeyDown;
        }

        /// <summary>
        /// 代码框按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CodeEditor_KeyDown(object sender, KeyEventArgs e)
        {
            Debug.Print("CodeEditor_KeyDown=" + e.Key.ToString());
            bool isEscKeyDown = CheckIsEscKeyDown(e);
            if (isEscKeyDown)
            {
                tb_search.Focus();
            }
        }

        /// <summary>
        /// 列表键盘输入事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListBox_KeyDown(object sender, KeyEventArgs e)
        {
            Debug.Print("ListBox_KeyDown=" + e.Key.ToString());
            bool isEscKeyDown = CheckIsEscKeyDown(e);
            if (isEscKeyDown)
            {
                tb_search.Focus();
            }
        }

        #region 窗体事件
        /// <summary>
        /// 窗体激活
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Activated(object sender, EventArgs e)
        {
            Growl.SetGrowlParent(GrowlPanel, true);
        }

        /// <summary>
        /// 窗体失去焦点,隐藏窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Deactivated(object sender, EventArgs e)
        {
            Debug.Print("SearchView.Window_Deactivated,窗体失去焦点");
            WindowUtil.Instance.Hide(GetType());
            Growl.SetGrowlParent(GrowlPanel, false);
        }

        /// <summary>
        /// 窗体关闭事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void Window_Closed(object sender, EventArgs e)
        {
            WindowUtil.Instance.Remove(GetType());
            WindowUtil.Instance.OnWindowShow -= OnWindowShow;
            MessageManager.CancelListening(MsgType.GrowMsg, growMsgListenID);
        }
        #endregion
    }
}
